package com.finger.crowd.mvc.config;

import com.finger.crowd.constant.CrowdConstant;
import com.finger.crowd.exception.AccessForbiddenException;
import com.finger.crowd.exception.LoginFailedException;
import com.finger.crowd.util.CrowdUtils;
import com.finger.crowd.util.ResultEntity;
import com.google.gson.Gson;
import org.springframework.dao.DuplicateKeyException;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

// 基于注解的异常处理
@ControllerAdvice
public class CrowdExceptionResolver {
    @ExceptionHandler(value = NullPointerException.class)
    public ModelAndView resolverNullpointerException(
            NullPointerException exception,
            HttpServletRequest req
            , HttpServletResponse resp) throws IOException {
        String viewName = "system-error";

        return commonResolver(viewName, exception, req, resp);
    }

    @ExceptionHandler(value = RuntimeException.class)
    public ModelAndView runtimeException(Exception exception,
                                         HttpServletRequest req,
                                         HttpServletResponse resp) throws IOException {
        String viewName = "system-error";
        return commonResolver(viewName, exception, req, resp);
    }

    @ExceptionHandler(value = AccessForbiddenException.class)
    public ModelAndView resolverAccessForbiddenException(
            Exception exception,
            HttpServletRequest req
            , HttpServletResponse resp) throws IOException {
        String viewName = "admin-login";

        return commonResolver(viewName, exception, req, resp);
    }

    @ExceptionHandler(value = DuplicateKeyException.class)
    public ModelAndView duplicateKeyException(Exception exception,
                                              HttpServletRequest req,
                                              HttpServletResponse resp) throws IOException {

        String viewName = "system-error";
        return commonResolver(viewName, exception, req, resp);
    }

    @ExceptionHandler(value = LoginFailedException.class)
    public ModelAndView resolverLoginFailedException(
            LoginFailedException exception,
            HttpServletRequest req
            , HttpServletResponse resp) throws IOException {

        // 登录失败后需要跳转到的页面
        String viewNane = "admin-login";

        return commonResolver(viewNane, exception, req, resp);
    }

    @ExceptionHandler(value = ArithmeticException.class)
    public ModelAndView resolverArithmeticException(Exception e,
                                                    HttpServletRequest req,
                                                    HttpServletResponse resp) throws IOException {
        String viewName = "system-error";
        return commonResolver(viewName, e, req, resp);
    }


    // 把公共的提取出来
    public ModelAndView commonResolver(String viewName, Exception exception, HttpServletRequest req, HttpServletResponse resp) throws IOException {
        // 判断当前请求是否为ajax请求
        boolean judgeResult = CrowdUtils.judgeRequestType(req);

        if (judgeResult) {
            // 如果是一个ajax请求
            ResultEntity<Object> failed = ResultEntity.failed(exception.getMessage());
            Gson gson = new Gson();
            String s = gson.toJson(failed);
            // 手动返回数据给浏览器
            resp.getWriter().write(s);
            return null;
        }
        // 如果不是ajax请求
        ModelAndView modelAndView = new ModelAndView();

        modelAndView.addObject(CrowdConstant.ATTR_NAME_EXCEPTION, exception);

        modelAndView.setViewName(viewName);

        return modelAndView;
    }

}
